Функции для работы с PDA:


🧩 create_pda(...)

    Создаёт новый PDA, если он ещё не существует.

    Проверяет, чтобы не было коллизии.

    Без записи данных.

🧩 write_to_pda(...)

    Просто записывает байты в существующий PDA.

    Без создания.

🧩 create_and_write_pda(...)

    Комбинированная функция.

    Сначала проверяет, есть ли PDA — если нет, создаёт.

    Затем записывает данные.

    Очень удобна для инициализации одного PDA в один вызов.

🧩 safe_read_pda(...)

    Возвращает Vec<u8> с содержимым PDA.

    Никогда не паникует: если PDA не существует или пустой — просто отдаёт Vec::new().

    Защита от двойного borrow'а (через try_borrow_data()).

    Отличный инструмент для безопасного считывания данных.

💡 Да, с этим ты можешь:
Возможность	Функция
📦 Создать PDA	create_pda
💾 Записать в PDA	write_to_pda
⚡ Создать и записать	create_and_write_pda
📖 Безопасно прочитать	safe_read_pda


🔧 create_pda(...)

🔹 Назначение:
Создаёт новый PDA-аккаунт, если он ещё не существует.

📥 Аргументы:

    pda_account: &AccountInfo — аккаунт, который хотим создать

    signer: &AccountInfo — аккаунт плательщика (обычно пользователь)

    system_program: &AccountInfo — системная программа

    program_id: &Pubkey — адрес текущей программы

    seeds: &[&[u8]] — массив сидов, по которым создавался PDA

    space: u64 — сколько байт выделить под данные

📤 Возвращает:

    Result<()> — Ok если успешно, Err если PDA уже существует или при ошибке создания

🧠 Особенности:

    Проверяет, что PDA ещё не создан (через pda_account.owner == Pubkey::default())

    Выбрасывает ErrCode::PdaAlreadyExists, если уже существует

🔧 write_to_pda(...)

🔹 Назначение:
Записывает бинарные данные в существующий PDA.

📥 Аргументы:

    pda_account: &AccountInfo — аккаунт, в который пишем

    data: &[u8] — массив байт, которые нужно записать

📤 Возвращает:

    Result<()> — Ok при успехе, Err если не удалось получить доступ к данным

🧠 Особенности:

    ⚠️ Только пишет, не создаёт PDA

    Записывает в начало data-секции аккаунта

🔧 create_and_write_pda(...)

🔹 Назначение:
Если PDA ещё не существует — создаёт, затем сразу записывает данные.

📥 Аргументы:

    pda_account: &AccountInfo — аккаунт для создания/записи

    signer: &AccountInfo — кто оплачивает создание

    system_program: &AccountInfo — системная программа

    program_id: &Pubkey — адрес текущей программы

    seeds: &[&[u8]] — сиды PDA

    data: Vec<u8> — данные для записи

    space: u64 — сколько байт выделить (при создании)

📤 Возвращает:

    Result<()> — Ok при успехе, Err при ошибке создания или записи

🧠 Особенности:

    Безопасно создаёт и пишет за один вызов

    Не выбрасывает ошибку, если PDA уже существует — просто пишет

🔧 safe_read_pda(...)

🔹 Назначение:
Безопасно считывает байты из PDA. Никогда не паникует.

📥 Аргументы:

    pda_account: &AccountInfo — аккаунт для чтения

📤 Возвращает:

    Vec<u8> — массив байт с содержимым PDA
    → Если аккаунт не инициализирован или пустой, возвращает Vec::new()

🧠 Особенности:

    Не выбрасывает ошибки — только логирует

    Полностью безопасно: подходит для чтения read-only PDA в любой ситуации